home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SunSoft Catalyst CDWARE 1996 May to August
/
Catalyst CDWARE 1996 May to August.iso
/
.products
/
.bin
/
httpd
/
src
/
http_get.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-18
|
7KB
|
247 lines
/*
* http_get.c: Handles things associated with GET
*
* All code contained herein is covered by the Copyright as distributed
* in the README file in the main directory of the distribution of
* NCSA HTTPD.
*
* Based on NCSA HTTPd 1.3 by Rob McCool
*
* 04-08-95 blong
* Fixed security hole which allowed a trailing slash on CGI_MAGIC_TYPE
* cgi anywhere scripts to send back the script contents. Now the
* trailing slash is added to the PATH_INFO, and the script is run.
* Oh yeah, and don't forget about directories.
*/
#include "httpd.h"
int header_only;
int num_includes;
int allow;
char allow_options;
void send_file(char *file, FILE *fd, struct stat *fi,
char *path_args, char *args)
{
FILE *f;
set_content_type(file);
if((allow_options & OPT_INCLUDES) && (!content_encoding[0])) {
#ifdef XBITHACK
if((fi->st_mode & S_IXUSR) ||
(!strcmp(content_type,INCLUDES_MAGIC_TYPE))) {
#else
if(!strcmp(content_type,INCLUDES_MAGIC_TYPE)) {
#endif
bytes_sent = 0;
send_parsed_file(file,fd,path_args,args,
allow_options & OPT_INCNOEXEC);
log_transaction();
return;
}
}
if(!(f=fopen(file,"r"))) {
log_reason("file permissions deny server access",file);
unmunge_name(file);
die(FORBIDDEN,file,fd); /* we've already established that it exists */
}
bytes_sent = 0;
if(!assbackwards) {
set_content_length(fi->st_size);
if (set_last_modified(fi->st_mtime,fd)) {
fclose(f);
return;
}
send_http_header(fd);
}
num_includes=0;
if(!header_only)
send_fd(f,fd,NULL);
log_transaction();
fclose(f);
}
/* Almost exactly equalivalent to exec_cgi_script, but this one
gets all of the path info passed to it, instead of calling get_path_info */
void send_cgi(char *method, char *file, char *path_args, char *args,
struct stat *finfo, int in, FILE *fd)
{
int m = M_GET;
int stub_returns;
if((!strcmp(method,"GET")) || (!strcmp(method,"HEAD")))
m = M_GET;
else if(!strcmp(method,"POST"))
m = M_POST;
else if(!strcmp(method,"PUT"))
m = M_PUT;
else if(!strcmp(method,"DELETE"))
m = M_DELETE;
evaluate_access(file,finfo,m,&allow,&allow_options,fd);
if((!allow) || (!(allow_options & OPT_EXECCGI))) {
log_reason("client denied by server configuration",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
if(!(in_headers_env = add_common_vars(in_headers_env,fd)))
die(NO_MEMORY,"send_cgi",fd);
bytes_sent = 0;
stub_returns = cgi_stub(method,file,path_args,args,in_headers_env,finfo,in,fd);
free_env(in_headers_env);
in_headers_env = NULL;
switch (stub_returns) {
case REDIRECT_URL:
die(REDIRECT,location,fd);
break;
case REDIRECT_LOCAL:
break;
default:
log_transaction();
break;
}
}
void send_node(char *file, char *args, int in, FILE *fd)
{
struct stat finfo;
char pa[MAX_STRING_LEN];
int length = 0;
register x = 0;
/* Remove all of the trailing slashes from the filename in order
to fix security hole. All trailing slashes are placed in the
path alias (pa) array */
length = strlen(file);
while (length && (file[length-1] == '/') && (x < MAX_STRING_LEN)) {
pa[x] = '/';
x++;
file[length-1] = '\0';
length--;
}
pa[x] = '\0';
if(stat(file,&finfo) == -1) {
/* Look for script or include document */
int n=count_dirs(file),i,l;
char t[MAX_STRING_LEN];
for(i=n;i;--i) {
make_dirstr(file,i,t);
probe_content_type(t);
if(!strcmp(content_type,CGI_MAGIC_TYPE)) {
if(stat(t,&finfo) == -1)
continue;
if(!(S_ISREG(finfo.st_mode)))
break;
l=strlen(t);
strncat(pa,&file[l],MAX_STRING_LEN - strlen(pa));
file[l] = '\0';
send_cgi("GET",file,pa,args,&finfo,in,fd);
return;
} else if(!strcmp(content_type,INCLUDES_MAGIC_TYPE)) {
if(stat(t,&finfo) == -1)
continue;
l=strlen(t);
strncat(pa,&file[l],MAX_STRING_LEN - strlen(pa));
file[l] = '\0';
goto send_regular;
}
}
if(errno==ENOENT) {
log_reason("file does not exist",file);
unmunge_name(file);
die(NOT_FOUND,file,fd);
}
else {
log_reason("file permissions deny server access",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
}
probe_content_type(file);
if(S_ISREG(finfo.st_mode) && (!strcmp(content_type,CGI_MAGIC_TYPE))) {
send_cgi("GET",file,pa,args,&finfo,in,fd);
return;
}
send_regular: /* aaaaack */
evaluate_access(file,&finfo,M_GET,&allow,&allow_options, fd);
if(!allow) {
log_reason("client denied by server configuration",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
if(S_ISDIR(finfo.st_mode)) {
char ifile[HUGE_STRING_LEN];
/* Path Alias (pa) array should now have the trailing slash */
/* if(file[strlen(file) - 1] != '/') { */
if (pa[0] != '/') {
char url[HUGE_STRING_LEN];
strcpy_dir(ifile,file);
unmunge_name(ifile);
construct_url(url,ifile);
escape_url(url);
die(REDIRECT,url,fd);
}
make_full_path(file,index_name,ifile);
if(stat(ifile,&finfo) == -1) {
if(allow_options & OPT_INDEXES)
index_directory(file,fd);
else {
log_reason("file permissions deny server access",file);
unmunge_name(file);
die(FORBIDDEN,file,fd);
}
}
else {
probe_content_type(ifile);
if(!strcmp(content_type,CGI_MAGIC_TYPE))
send_cgi("GET",ifile,pa,args,&finfo,in,fd);
else
send_file(ifile,fd,&finfo,pa,args);
}
return;
}
if(S_ISREG(finfo.st_mode))
send_file(file,fd,&finfo,pa,args);
else {
log_reason("improper file type",file);
unmunge_name(file);
die(FORBIDDEN,file,fd); /* device driver or pipe, no permission */
}
}
void process_get(int in, FILE *out, char *m, char *url, char *args) {
int s;
if(assbackwards && header_only) {
header_only = 0;
die(BAD_REQUEST,"Invalid HTTP/0.9 method.",out);
}
s=translate_name(url,out);
switch(s) {
case STD_DOCUMENT:
send_node(url,args,in,out);
return;
case REDIRECT_URL:
die(REDIRECT,url,out);
case SCRIPT_NCSA:
exec_get_NCSA(url,args,in,out);
return;
case SCRIPT_CGI:
exec_cgi_script(m,url,args,in,out);
return;
}
}